export default class GuidelineManager {
    constructor(d3, canvas) {
        this.d3Instance = d3;
        this.canvas = canvas;
        this.GUIDELINE_COLOR = "#ff3366"; // 参考线颜色
        this.GUIDELINE_STROKE_WIDTH = 1; // 参考线宽度
        this.guidelines = canvas.append("g").attr("class", "guidelines");
    }

    ensureNumber = (value, defaultValue = 0) => {
        return isNaN(value) ? defaultValue : value;
    };

    clear = () => {
        this.canvas.selectAll("line").remove();
    }
    
    draw = (snaps, currentElement) => {
        this.clear();
        
        const lines = snaps.map((snap, i) => {
            let x1, y1, x2, y2;
            const target = snap.target;
            const current = {
                x: Number(currentElement.attr('x')),
                y: Number(currentElement.attr('y')),
                width: Number(currentElement.attr('width')),
                height: Number(currentElement.attr('height'))
            };

            const targetX = Number(target.selection.attr('x'));
            const targetWidth = Number(target.selection.attr('width'));
            const targetY = Number(target.selection.attr('y'));
            const targetHeight = Number(target.selection.attr('height'));
            
            switch(snap.type) {
                case 'left':
                case 'rightToLeft':
                case 'leftToRight':
                case 'centerX':
                    
                    const x = snap.type === 'centerX' ? 
                        targetX + targetWidth / 2 : 
                        (snap.type === 'left' ? targetX : 
                        (snap.type === 'rightToLeft' ? targetX : targetX + targetWidth));
                    
                    // 水平线，覆盖两个元素的高度范围
                    y1 = Math.min(current.y, targetY);
                    y2 = Math.max(current.y + current.height, targetY + targetHeight);
                    x1 = x2 = this.ensureNumber(x);
                    break;
                    
                case 'top':
                case 'bottomToTop':
                case 'topToBottom':
                case 'centerY':
                    const y = snap.type === 'centerY' ? 
                        targetY + targetHeight / 2 : 
                        (snap.type === 'top' ? targetY : 
                        (snap.type === 'bottomToTop' ? targetY : targetY + targetHeight));
                    
                    // 垂直线，覆盖两个元素的宽度范围
                    x1 = Math.min(current.x, target.x);
                    x2 = Math.max(current.x + current.width, target.x + target.width);
                    y1 = y2 = this.ensureNumber(y);
                    break;
                    
                case 'right':
                    x1 = x2 = this.ensureNumber(targetX + targetWidth);
                    y1 = Math.min(current.y, targetY);
                    y2 = Math.max(current.y + current.height, targetY + targetHeight);
                    break;
                    
                case 'bottom':
                    y1 = y2 = this.ensureNumber(targetY + targetHeight);
                    x1 = Math.min(current.x, targetX);
                    x2 = Math.max(current.x + current.width, targetX + targetWidth);
                    break;
            }
            
            return { x1, y1, x2, y2, id: `guideline-${i}` };
        });
        
        // 绘制参考线
        this.guidelines.selectAll("line")
            .data(lines)
            .enter()
            .append("line")
            .attr("id", d => d.id)
            .attr("x1", d => this.ensureNumber(d.x1))
            .attr("y1", d => this.ensureNumber(d.y1))
            .attr("x2", d => this.ensureNumber(d.x2))
            .attr("y2", d => this.ensureNumber(d.y2))
            .attr("stroke", this.GUIDELINE_COLOR)
            .attr("stroke-width", this.GUIDELINE_STROKE_WIDTH)
            .attr("stroke-dasharray", "4,2")
            .attr("pointer-events", "none");
    }
}